/* 
 * File:   Div.cpp
 * Author: Gab'z
 * 
 * Created on 3 juin 2012, 22:42
 */

#include "Div.h"
#include "../../../Context.h"
#include "../../literal/Stack.h"
#include "../../literal/Complex.h"
#include "../../literal/Integer.h"
#include "../../literal/Rationnal.h"

namespace calculator {
    Logger* Div::log = LoggerManager::getInstance()->getLogger("Div");

    Div::Div(const std::string name) : BinaryOperator(name) {
    }

    Div::Div(const Div& orig) : BinaryOperator(orig._name) {
    }

    Div::~Div() {
    }

    Div* Div::clone() const {
        return new Div(_name);
    }

    const Number* Div::apply(const Number* denom, const Number* num) const throw (ArithmeticException) {
        if ((dynamic_cast<const Complex*> (num) != 0 || dynamic_cast<const Complex*> (denom) != 0)
                && Context::getInstance()->getParameters()->getComplexMode() == false) throw ArithmeticException("Complex mode OFF");
        const Number* n;
        const Integer* intNum = dynamic_cast<const Integer*> (num);
        const Integer* intDenom = dynamic_cast<const Integer*> (denom);
        try {
            if (intNum != 0 && intDenom != 0) {
                log->debug("Division de 2 entiers");
                if (Context::getInstance()->getParameters()->getIntegerDivision() == true) {
                    log->debug("Division entiere autorisée");
                    // division entière autorisée, c'est le comportement naturel des nombres
                    n = div(intNum, intDenom);
                } else {
                    log->debug("Division entiere refusée, conversion auto");

                    // else on conserve la précision en transformant le numen rationnel
                    Rationnal* ratNum = new Rationnal(*intNum);
                    n = new Rationnal(*ratNum / *intDenom);
                    delete ratNum;
                }
            } else {
                n = div(num, denom);
            }




            //            
            //            if (Context::getInstance()->getParameters()->getIntegerDivision() == false && integer != 0) {
            //                // division avec un entier au num
            //                // conversion en rationnel pour avoir au moins une division de 
            //                // rationnels et conserver la précision
            //
            //                
            //
            //
            //            } else {
            //                // division entière
            //                n = div(num, denom);
            //
            //            }




        } catch (ArithmeticException& e) {
            throw;
        }
        return n;
    }
}